package cwinsor.com.leaf_raking;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import cwinsor.com.leaf_raking.Person.Format;

abstract public class FileTypeSchedulePreferences extends FileType {

	/* 
	 * local variables - column numbers
	 */
	protected Integer colSkip;
	protected Integer colFirstInitial;
	protected Integer colLastName;
	protected Integer colAvailCurrentBase;
	protected Integer colEnd;


	/**
	 * constructor
	 */
	public FileTypeSchedulePreferences() {

		// establish column numbers
		colSkip = 0;
		colFirstInitial = 1; 
		colLastName = 2;
		colAvailCurrentBase = 3;
		colEnd = 15;
	}


	///////////////
	// column getters
	public Integer colSkip() { return colSkip; }
	public Integer colFirstInitial() { return colFirstInitial; }
	public Integer colLastName() { return colLastName; }

	public Integer colAvailCurrent(WorkShift workShift) {
		return colAvailCurrentBase + workShift.toIndex();
	}

	public Integer colEnd() { return colEnd; }

	@Override
	public void doPopulate(
			ArrayList<String> theFieldsObject,
			ArrayList<Person> persons,
			Boolean supervisors) {

		Msg.fatal(dS + ": not supported");
	}

	@Override
	protected void doWriteToFile(Person person, PrintWriter writer,
			Format format) {

		Msg.fatal(dS + ": not supported");
	}


	/*
	 * update data from array of fields
	 */
	@Override
	public void doApplySchedulePreferenceUpdates(
			ArrayList<String> theFieldsObject,
			PrsnList personList) {

		// if the line starts with "SKIP" then skip it
		if (theFieldsObject.get(colSkip()).equals("SKIP")) {
			//Msg.note(dS + ": skipping line" + theFieldsObject.toString());
			return;
		}

		Msg.note(dS + ": updating from line" + theFieldsObject.toString());

		// sanity checks
		// confirm there are enough fields
		if (theFieldsObject.size() != colEnd()+1) {
			Msg.fatal(dS + ": number of columns incorrect..."
					+ " last column (index) = " + colEnd()
					+ " but theFieldsObject.size() = "
					+ theFieldsObject.size()
					+ " (should be " + (colEnd()+1));
		}
		// confirm the line ends with "END"
		if (!theFieldsObject.get(colEnd()).equals("END")) {
			Msg.fatal(dS + ": the last column (number " + colEnd() + ") should be \"END\"");
		}

		// find person(s) using first initial, last name
		ArrayList<Person> matchingPersons = new ArrayList<Person>();

		// the derived class will use
		// first initial last name
		// or
		// first name last name
		doFindPersons(theFieldsObject.get(colFirstInitial()),
				theFieldsObject.get(colLastName()),
				personList,
				matchingPersons);

		// hold a reference to the person
		Person thePerson = matchingPersons.get(0);

		// current availability becomes last availability
		for (WorkShift workShift : WorkShift.asList()) {

			// propagate

			// current availability 
			// if there is no current apply a "0"
			if ((thePerson.valAvailCurrent.get(workShift) == null) || (thePerson.valAvailCurrent.get(workShift).equals("")))  {
				thePerson.valAvailCurrent.put(workShift, 0);
			}
			// propagate current to last
			thePerson.valAvailLast.put(workShift, thePerson.valAvailCurrent.get(workShift));

			// next - if user has entered a value - apply that to current
			String tempS = theFieldsObject.get(colAvailCurrent(workShift));
			if ((tempS == null) || (tempS.equals(""))) {
				// do nothing
			}
			else  {
				Integer tempI = null;
				if      (tempS.equals("-2")) tempI = -2;
				else if (tempS.equals("-1")) tempI = -1;
				else if (tempS.equals("0"))  tempI =  0;
				else if (tempS.equals("1"))  tempI =  1;
				else if (tempS.equals("2"))  tempI =  2;
				else {
					Msg.fatal(dS + ": unable to convert the update preference field \"" + tempS + "\" into [-2, -1, 0, 1]");
				}
				thePerson.valAvailCurrent.put(workShift, tempI);
			}
		}
	}

	protected abstract void doFindPersons(
			String firstName,
			String lastName,
			PrsnList personList,
			ArrayList<Person> matchingPersons);


	// debug
	String dS = this.getClass().getSimpleName();
}